package Thread;/*
 *
 *@author:    Xavier
 *@data:      2024 - 01 - 12
 *@time:      15:58
 *
 */


// 线程安全

/*
* 产生原因：
* 1、多个线程之间的调度顺序是“随机的”，OS使用“抢占式”执行的策略 - 主要原因
* 2、多个线程同时修改同一个变量，容易产生线程安全问题
* 3、进行的修改不是原子操作 - 主要解决的切入点，用加锁
* 4、内存可见性，引起的线程安全问题
* */

// 加锁 - synchronized
//把不是原子的操作，打包成一个原子，通过”互斥“来保证
// 事物中的原子性，是通过“回滚”机制来保证
class Counter {
    public int count = 0;

//    synchronized void increase() {
//        // 这里加了synchronized
//        // 进了方法就会加锁(lock)，出了方法就会解锁(unlock)
//        ++count;
//    }
    void increase() {
        synchronized (this) {
            count++;
        }
    }
    //使用synchronized，其实是指定了某个具体的对象进行加锁，
    //当synchronized直接修饰方法，此时就相当于是针对this加锁，就是简化的写法
    //这里的 this 都指的是 Counter 这个对象


    public synchronized static void func() {
        //这里的synchronized是对 类对象 进行加锁
    }
}


public class Demo12 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println(counter.count);


    }
}
